<script setup lang="ts" name="RaceBar">
import API from "@/api";
import { userinfo } from "@/store";
import { colors } from "@/const/color";
import gsap from "gsap";
import CustomEase from "gsap/CustomEase";
import dayjs from "dayjs";
gsap.registerPlugin(CustomEase);
const route = useRoute();
const router = useRouter();
const { t } = useI18n();
const piniaUserinfo: any = userinfo();

const global: any = getCurrentInstance()?.appContext.config.globalProperties;
let timer: any;
let gsapCtx: any;

const easeTypes = [
  "M0,0 C0.325,0.402 0.816,0.598 1,1 ",
  "M0,0 C0.153,0.341 0.749,0.723 1,1 ",
  "M0,0 C0.355,0.371 0.732,0.62 1,1 ",
  "M0,0 C0.325,0.402 0.732,0.62 1,1 ",
  "M0,0 C0.388,0.35 0.668,0.637 1,1 ",
  "M0,0 C0.364,0.385 0.755,0.69 1,1 ",
  "M0,0 C0.39,0.32 0.755,0.69 1,1 ",
  "M0,0 C0.349,0.358 0.816,0.598 1,1 ",
  "M0,0 C0.395,0.316 0.693,0.624 1,1 ",
  "M0,0 C0.379,0.346 0.723,0.598 1,1 ",
  "M0,0 C0.356,0.363 0.687,0.62 1,1 ",
  "M0,0 C0.373,0.347 0.725,0.617 1,1 ",
  "M0,0 C0.317,0.374 0.694,0.629 1,1 ",
  "M0,0 C0.367,0.295 0.719,0.623 1,1 ",
  "M0,0 C0.692,0.673 0.719,0.623 1,1 ",
  "M0,0 C0.709,0.637 0.426,0.356 1,1 ",
  "M0,0 C0.742,0.606 0.395,0.378 1,1 ",
];

const emits = defineEmits(["getNewGame"]);

const props = defineProps({
  mapStatusIndex: {
    type: Number,
    default: 0,
  },
  isStart: {
    type: Boolean,
    default: false,
  },
  winningNumber: {
    type: String,
  },
  time: {
    type: Number,
    default: 0,
  },
  period: {
    type: String,
  },
  betRecord: {
    type: Object,
    default: {
      record5: [],
      recordRank: [],
    },
  },
  nextTime: {
    type: Number,
    default: 0,
  },
  timeInfo: {
    type: Number,
    default: 0,
  },
  endTime: {
    type: Number,
    default: 0,
  },
});

const data: any = reactive({
  currentRanking: [], // 实时位置
  rankIndex: 0,
  thCurrentRanking: [], // 节流顺序
  rankRefs: [], // 赛道gsap动画实例
  roadsRef: null, // gsap赛道获取dom
  realsRef: null, // 模拟赛马获取houseDom
  isFinish: false,
  rankTime: 0,
});

const {
  currentRanking,
  rankIndex,
  thCurrentRanking,
  rankRefs,
  roadsRef,
  realsRef,
  isFinish,
  rankTime,
} = toRefs(data);

const houseList = computed(() => {
  return colors.map((it, index) => {
    return {
      ...it,
      house: new URL(`../../../assets/images/Race/66-${index+1}.gif`, import.meta.url)
        .href,
    };
  });
});

// 随机生成的8个排序
const sortedEase = computed(() => {
  let seed = props.endTime;
  const random = (min: number, max: number) =>
    Math.sin(seed++) * (max - min) + min;
  return easeTypes.sort(() => random(-1, 1)).slice(0, 8);
});

// 期数
const RaceId = computed(() => {
  return props.period;
});

// 重新排序
const rankingSort = computed(() => {
  return currentRanking.value?.sort((a: any, b: any) => b.val - a.val);
});
watchDebounced(
  () => rankIndex.value,
  () => {
    thCurrentRanking.value = rankingSort.value?.map((it: any) => it?.number);
  },
  {
    debounce: 1000,
    maxWait: 500,
  }
);

// 5场记录
const betRecord5 = computed(() => {
  return props.betRecord.record5.map((item: any) => {
    return Array.from(String(item?.winningNumber))
      .map((it: string, index: number) => {
        return {
          rank: index + 1,
          value: +it,
        };
      })
      .sort((a: any, b: any) => a.value - b.value);
  });
});

// 30场记录
const betRecord30 = computed(() => {
  return (
    props.betRecord.recordRank || [].sort((a: any, b: any) => b?.key - a?.key)
  );
});

// 最近5场冠亚季
const latRecord5 = computed(() => {
  return props.betRecord.record5.map((item: any) => {
    return {
      time: dayjs(+item.endTime).format("HH:mm"),
      nums: item?.winningNumber.split("").splice(0, 3),
    };
  });
});

// 当前比赛结果
const currentWinNumber = computed(() => {
  return (
    (props?.winningNumber &&
      Array.from(String(props?.winningNumber))
        .map((it: string, index: number) => {
          return {
            rank: index + 1,
            value: +it,
          };
        })
        .sort((a: any, b: any) => a.value - b.value)) ||
    []
  );
});

const rankList = computed(() => {
  return (
    props?.winningNumber &&
    Array.from(String(props?.winningNumber))
      .map((it: string, index: number) => {
        return {
          rank: index + 1,
          value: +it,
        };
      })
      .sort((a: any, b: any) => a.rank - b.rank)
  );
});

const backLastPage = () => {
  router.back();
};

const startCountdown = () => {
  clearInterval(timer);
  timer = setInterval(() => {
    if (rankTime.value > 0) {
      rankTime.value--;
    } else {
      clearInterval(timer);
      // 倒计时结束后的操作
    }
  }, 1000); // 每秒执行一次
};

// 暂停所有动画
const handlePauseAllAnimations = (rank: number) => {
  if (rank >= 3) {
    rankRefs.value.forEach((element: any) => {
      element?.pause();
    });
    // 显示排名并倒计时
    rankIndex.value = 0;
    currentRanking.value = [];
    isFinish.value = true;
  }
};

const handlePlay = (time: number = 0) => {
  rankRefs.value.forEach((element: any) => {
    element?.restart();
  });
};

// 模拟赛马动画
const handleInitRealAni = () => {
  if (currentWinNumber.value?.length < 1) return;
  // 执行动画
  rankRefs.value = [];
  let seekTime =
    props.timeInfo < props.nextTime ? props.nextTime - props.timeInfo : 0;
  if (seekTime > 32) {
    isFinish.value = true;
    return;
  }
  // let seekTime = 0;
  console.log("seekTime", seekTime);
  gsapCtx = gsap.context((self: gsap.Context) => {
    const rounds = self?.selector?.(".realHouse");
    const roundBg = self?.selector?.(".realBg");
    const roundWrap = self?.selector?.(".realWrap");
    const roundWrapWidth = roundWrap[0].getBoundingClientRect()?.width;
    if (rounds) {
      console.log("sortedEase.value", props.endTime, sortedEase.value);
      for (let i = 0; i < colors.length; i++) {
        rankRefs.value[i] = gsap
          .timeline({
            paused: true,
          })
          .to(rounds[i], {
            left: `calc(100% - 10% - 53rem)`,
            duration: 30 + currentWinNumber.value[i].rank * 0.4,
            ease: CustomEase.create("custom", sortedEase.value[i]),
          })
          .play(seekTime);
      }
    }
    if (roundBg && roundWrapWidth) {
      gsap
        .timeline({})
        .to(roundBg[0], {
          left: `calc(-1000% + ${roundWrapWidth}rem)`,
          duration: 30 + 1 * 0.4,
          ease: CustomEase.create("custom", sortedEase.value[0]),
        })
        .play(seekTime);
    }
  }, realsRef.value);
};

// 赛马轨道
const handleInitAni = () => {
  if (currentWinNumber.value?.length < 1) return;
  // 执行动画
  rankRefs.value = [];
  let seekTime =
    props.timeInfo < props.nextTime ? props.nextTime - props.timeInfo : 0;
  if (seekTime > 32) {
    isFinish.value = true;
    return;
  }
  console.log("seekTime", seekTime);
  gsapCtx = gsap.context((self: gsap.Context) => {
    const rounds = self?.selector?.(".round");
    if (rounds) {
      console.log("sortedEase.value", props.endTime, sortedEase.value);
      for (let i = 0; i < colors.length; i++) {
        rankRefs.value[i] = gsap
          .timeline({
            paused: true,
            onUpdate: () => {
              let currentLeft = rounds[i].getBoundingClientRect().left;
              rankIndex.value += 1;
              currentRanking.value[i] = {
                number: i + 1,
                val: currentLeft,
              };
            },
            onComplete: () =>
              handlePauseAllAnimations(currentWinNumber.value[i].rank),
          })
          .to(rounds[i], {
            left: `calc(100% - 10% - 17rem)`,
            duration: 30 + currentWinNumber.value[i].rank * 0.4,
            ease: CustomEase.create("custom", sortedEase.value[i]),
          })
          .play(seekTime);
      }
    }
  }, roadsRef.value);
};

// 开始动画
watch(
  () => props.isStart,
  (val) => {
    if (!!val) {
      isFinish.value = false;
      rankTime.value =
        props.timeInfo < props.nextTime ? props.timeInfo : props.nextTime;
      startCountdown();
      if (props.nextTime && props.nextTime < 40) {
        isFinish.value = true;
        return;
      }
      // 执行动画
      nextTick(() => {
        handleInitAni();
        handleInitRealAni();
      });
    } else {
      gsapCtx?.revert();
    }
  },
  {
    immediate: true,
  }
);
onUnmounted(() => {
  gsapCtx?.revert();
});

watch(
  () => rankTime.value,
  (val) => {
    if (val <= 0) {
      isFinish.value = false;
      currentRanking.value = [];
      emits("getNewGame");
    }
  }
);
</script>

<template>
  <div v-if="!isFinish">
    <div class="raceBar">
      <van-icon
        class="back"
        name="arrow-left"
        color="#FFF"
        @click="backLastPage"
      />
      <div class="title">
        {{ t("bet.bet25") }}
        <span>{{ RaceId }}</span>
        {{ t("bet.bet26") }}
      </div>

      <div class="realRoad" ref="realsRef">
        <div class="realWrap">
          <div class="realBg">
            <div class="left"></div>
            <div class="center"></div>
            <div class="right"></div>
          </div>
          <img
            v-for="(item, index) in houseList"
            :key="item.id"
            class="realHouse"
            v-show="isStart"
            :style="{
              top: `${index * 23 + 14}rem`,
            }"
            :src="item.house"
          />
        </div>
      </div>

      <!-- 左侧排序 -->
      <TransitionGroup tag="ul" name="fade" class="leftRank">
        <li
          v-for="(item, index) in thCurrentRanking"
          :key="item"
          class="rankItem"
          :class="{
            top: index < 3,
          }"
          :style="{ backgroundColor: colors[item - 1]?.bg }"
        >
          {{ item }}
        </li>
      </TransitionGroup>

      <!-- 记录 -->
      <div class="raceRecord" v-if="!!mapStatusIndex">
        <div v-if="mapStatusIndex === 1" class="record1">
          <div class="recordHeader">
            <img src="@/assets/images/Race/raceCup.png" alt="" />
            <p>{{ t("bet.bet30") }}</p>
          </div>
          <div class="recordContent">
            <div class="rankList">
              <div
                class="rankItem"
                v-for="(it, i) in colors"
                :key="i"
                :style="{
                  backgroundColor: it.bg,
                  borderColor: it.border,
                }"
              >
                {{ i + 1 }}
              </div>
            </div>
            <div class="recordTable">
              <div class="row" v-for="(item, index) in betRecord5" :key="index">
                <div
                  class="column"
                  v-for="(it, i) in item"
                  :key="i"
                  :class="{
                    rank1: it?.rank == 1,
                    rank2: it?.rank == 2,
                    rank3: it?.rank == 3,
                  }"
                >
                  {{ it?.rank }}
                </div>
              </div>
            </div>
          </div>
        </div>
        <div v-if="mapStatusIndex === 2" class="record2">
          <div class="recordHeader">
            <img src="@/assets/images/Race/raceCup.png" alt="" />
            <p>{{ t("bet.bet31") }}</p>
          </div>
          <div class="recordContent">
            <div class="rankList">
              <div
                class="rankItem"
                v-for="(it, i) in colors"
                :key="i"
                :style="{
                  backgroundColor: it.bg,
                  borderColor: it.border,
                }"
              >
                {{ i + 1 }}
              </div>
            </div>
            <div class="recordTable">
              <div
                class="row"
                v-for="(item, index) in betRecord30"
                :key="index"
              >
                <div class="column" v-for="(it, i) in item.sm" :key="i">
                  <img
                    v-if="it?.rank === 1"
                    src="@/assets/images/Race/prize1.png"
                    alt=""
                  />
                  <img
                    v-else-if="it?.rank === 2"
                    src="@/assets/images/Race/prize2.png"
                    alt=""
                  />
                  <img
                    v-else-if="it?.rank === 3"
                    src="@/assets/images/Race/prize3.png"
                    alt=""
                  />
                  <span>{{ it?.num }}</span>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div v-if="mapStatusIndex === 3" class="record3">
          <div class="recordHeader">
            <img src="@/assets/images/Race/raceCup.png" alt="" />
            <p>{{ t("bet.bet32") }}</p>
          </div>
          <div class="recordContent">
            <div class="recordTable">
              <div class="row" v-for="(item, index) in latRecord5" :key="index">
                <div>{{ item?.time }}</div>
                <div class="column" v-for="(it, i) in item.nums" :key="i">
                  <img
                    v-if="i === 0"
                    src="@/assets/images/Race/prize1.png"
                    alt=""
                  />
                  <img
                    v-else-if="i === 1"
                    src="@/assets/images/Race/prize2.png"
                    alt=""
                  />
                  <img
                    v-else-if="i === 2"
                    src="@/assets/images/Race/prize3.png"
                    alt=""
                  />
                  <div
                    class="num"
                    :style="{
                      backgroundColor: colors[it - 1].bg,
                      borderColor: colors[it - 1].border,
                    }"
                  >
                    {{ it }}
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 倒计时 -->
      <div class="timeStart" v-if="time > 0">
        <p>
          {{ t("bet.bet23") }} <span>{{ time }}</span>
        </p>
      </div>
    </div>
    <!-- 赛道 -->
    <Transition :duration="550" name="road">
      <div v-show="isStart" class="raceRoad">
        <div class="startLeft">{{ t("bet.bet24") }}</div>
        <div class="roads" ref="roadsRef">
          <div class="road" v-for="(item, index) in colors" :key="item.id">
            <span
              class="round"
              :style="{
                backgroundColor: item.bg,
              }"
            >{{item.id}}</span>
          </div>
          <div class="endRight"></div>
        </div>
      </div>
    </Transition>
  </div>

  <!-- 排名前三 -->
  <div class="rankThree" v-else>
    <van-icon
      class="back"
      name="arrow-left"
      color="#FFF"
      @click="backLastPage"
    />
    <div class="title">
      {{ t("bet.bet25") }}
      <span>{{ RaceId }}</span>
      {{ t("bet.bet26") }}
    </div>
    <div class="two">
      <img class="crown" src="@/assets/images/Race/2.png" alt="" />
      <div
        class="box"
        :style="{
          backgroundColor: rankList && colors[rankList[1].value - 1].bg,
          borderColor: rankList && colors[rankList[1].value - 1].border,
        }"
      >
        {{ rankList && rankList[1].value }}
      </div>
      <img class="ped" src="@/assets/images/Race/2bg.png" alt="" />
    </div>
    <div class="one">
      <img class="crown" src="@/assets/images/Race/1.png" alt="" />
      <div
        class="box"
        :style="{
          backgroundColor: rankList && colors[rankList[0].value - 1].bg,
          borderColor: rankList && colors[rankList[0].value - 1].border,
        }"
      >
        {{ rankList && rankList[0].value }}
      </div>
      <img class="ped" src="@/assets/images/Race/1bg.png" alt="" />
    </div>
    <div class="three">
      <img class="crown" src="@/assets/images/Race/3.png" alt="" />
      <div
        class="box"
        :style="{
          backgroundColor: rankList && colors[rankList[2].value - 1].bg,
          borderColor: rankList && colors[rankList[2].value - 1].border,
        }"
      >
        {{ rankList && rankList[2].value }}
      </div>
      <img class="ped" src="@/assets/images/Race/3bg.png" alt="" />
    </div>

    <div class="timeStart" v-if="rankTime > 0">
      <p>
        {{ t("bet.bet33") }} <span>{{ rankTime }}</span>
      </p>
    </div>
  </div>
</template>

<style lang="scss" scoped>
@import url("./index.scss");
</style>
